package ua.amsoft.brelok.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.util.Log;

/**
 * @author Tair Mustafaiev
 */
public class DateTimeUtils {
    
    private static final String TAG = "DateTimeUtils";
    
    /**
     * Calculates Beginning of the working day related to current time
     * 
     * @param timeFrom - time of the beginning of the working day
     * @param timeTill - time of the ending of the working day
     * @return {@link Date} beginning of the working day. According to the
     *         current time, date - today's date will be returned or tomorrow's
     *         date of beginning
     */
    public static Date calculateBeginingOfDay(final String timeFrom, final String timeTill) {
        final String fromHoursAndMinutes[] = timeFrom.split(":");
        final String tillHoursAndMinutes[] = timeTill.split(":");
        
        final Calendar currentCalendar = getCurrentDate();
        final Calendar beginningCalendar = getCalendarInstanceForTime(fromHoursAndMinutes);
        final Calendar endingCalendar = getCalendarInstanceForTime(tillHoursAndMinutes);
        
        if (beginningCalendar.before(currentCalendar) && currentCalendar.after(endingCalendar)) {
            // here we need to add 1 day
            beginningCalendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        Log.i("DateTimeUtils", "Execution date is setted to: "
                + beginningCalendar.getTime().toString());
        
        return beginningCalendar.getTime();
    }
    
    /**
     * Calculates ending of the working day related to current time
     * 
     * @param timeTill - time of the ending of the working day
     * @return {@link Date} ending of the working day. According to the current
     *         time, date - today's date will be returned or tomorrow's date of
     *         ending
     */
    public static Date calculateEndOfDay(final String timeTill) {
        final String tillHoursAndMinutes[] = timeTill.split(":");
        
        final Calendar currentCalendar = getCurrentDate();
        final Calendar endingCalendar = getCalendarInstanceForTime(tillHoursAndMinutes);
        
        if (endingCalendar.before(currentCalendar)) {
            // here we need to add 1 day
            endingCalendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        Log.i("DateTimeUtils", "Execution date is setted to: "
                + endingCalendar.getTime().toString());
        
        return endingCalendar.getTime();
    }
    
    /**
     * Checks is current time is between updatable time
     * 
     * @param timeFrom - time of the beginning of the working day
     * @param timeTill - time of the ending of the working day
     * @return - <code> boolean true</code> if the time in between otherwise
     *         <code>false</code>
     */
    public static boolean isNowUpdatablePeriod(final String timeFrom, final String timeTill) {
        final String fromHoursAndMinutes[] = timeFrom.split(":");
        final String tillHoursAndMinutes[] = timeTill.split(":");
        final Calendar currentCalendar = getCurrentDate();
        final Calendar beginningCalendar = getCalendarInstanceForTime(fromHoursAndMinutes);
        final Calendar endingCalendar = getCalendarInstanceForTime(tillHoursAndMinutes);
        if (currentCalendar.after(beginningCalendar) && currentCalendar.before(endingCalendar)) {
            return true;
        }
        return false;
    }
    
    /**
     * Formats passed date for input purposes
     * 
     * @param date - {@link Date} date to be formatted
     * @return formatted date string
     */
    public static String formatInputDate(final Date date) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return dateFormat.format(date);
    }
    
    /**
     * Formats passed string to output date format
     * 
     * @param date {@link String} date to be formatted
     * @return formatted {@link Date}
     */
    public static Date parseOutputDate(final String date) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            return dateFormat.parse(date);
        } catch (final ParseException e) {
            Log.e(DateTimeUtils.TAG, e.getLocalizedMessage());
        }
        return new Date();
    }
    
    /**
     * @return {@link Calendar} instance with current date and time
     */
    private static Calendar getCurrentDate() {
        final Calendar currentCalendar = Calendar.getInstance();
        currentCalendar.get(Calendar.HOUR_OF_DAY);
        currentCalendar.get(Calendar.MINUTE);
        currentCalendar.set(Calendar.SECOND, 0);
        currentCalendar.set(Calendar.MILLISECOND, 0);
        return currentCalendar;
    }
    
    /**
     * @param hoursAndMinutes - to be setted to calendar
     * @return {@link Calendar} according to the setted time
     */
    private static Calendar getCalendarInstanceForTime(final String[] hoursAndMinutes) {
        final Calendar beginningCalendar = Calendar.getInstance();
        final int fromHour = Integer.valueOf(hoursAndMinutes[0]);
        final int fromMinute = Integer.valueOf(hoursAndMinutes[1]);
        beginningCalendar.set(Calendar.HOUR_OF_DAY, fromHour);
        beginningCalendar.set(Calendar.MINUTE, fromMinute);
        beginningCalendar.set(Calendar.SECOND, 0);
        beginningCalendar.set(Calendar.MILLISECOND, 0);
        return beginningCalendar;
    }
}
